package com.ym.medical.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.ym.base.enums.FlagEnum;
import com.ym.core.exception.BusinessException;
import com.ym.core.utils.tkmybatis.BaseSVImpl;
import com.ym.core.utils.tkmybatis.TK;
import com.ym.medical.dao.CouponDao;
import com.ym.medical.domain.entity.CouponEntity;
import com.ym.medical.domain.entity.DoctorServicePriceEntity;
import com.ym.medical.domain.param.CouponParam;
import com.ym.medical.domain.param.CouponQryParam;
import com.ym.medical.domain.vo.CouponVo;
import com.ym.medical.enums.CouponChannelEnum;
import com.ym.medical.enums.CouponSendWayEnum;
import com.ym.medical.enums.CouponTypeEnum;
import com.ym.medical.enums.CouponValidModelEnum;
import com.ym.medical.service.ICouponSV;
import com.ym.medical.service.IDoctorServicePriceSV;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
* 优惠劵Service业务层处理
*
* @author ym
* @date 2020-09-15
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class CouponSVImpl extends BaseSVImpl<CouponEntity,CouponDao> implements ICouponSV {

	@Autowired
	private IDoctorServicePriceSV iPriceSV;

	/**
	 *医生端或者患者端兑换
	 * 不可使用过滤方法
	 * @param pageNo
	 * @param limit
	 * @param couponModel
	 * @return
	 */
	@Override
	public PageInfo<CouponVo> couponList(int pageNo, int limit, CouponParam couponModel) {
		//isSys 01 医生端优惠券参数  02 患者端将康币兑换传参
		PageHelper.startPage(pageNo,limit);
		couponModel.setPubState("01");
		couponModel.setCondition(true);
		List<CouponVo> couponList = mapper.couponList(couponModel);
		return  new PageInfo<>(couponList);
	}


	/**
	 * 我的优惠券
	 * @param pageNo
	 * @param pageSize
	 * @param couponModel
	 * @return
	 */
	@Override
	public PageInfo<CouponVo> myCoupon(int pageNo, int pageSize, CouponParam couponModel) {
		Page<CouponVo> page = PageHelper.startPage(pageNo,pageSize);
		List<CouponVo> myCoupon = null;
		String toSb = null;
		List<CouponVo> newCoupon = new ArrayList<>();
		if (couponModel.getDoctId() != null){
			if (StringUtil.isEmpty(couponModel.getToSb())){
				throw new BusinessException("参数 toSb = '"+couponModel.getToSb()+"'");
			}else {
				toSb = couponModel.getToSb();
			}
			couponModel.setToSb(toSb);
			myCoupon = mapper.myCoupon(couponModel);
			//myCoupon = couponFilter(myCoupon,true);
			DoctorServicePriceEntity servicePrice = iPriceSV.selectById(couponModel.getPriceId());
			BigDecimal price = servicePrice.getDspPrice();
			for (CouponVo vo : myCoupon) {
				//医生发送 || 兑换
				boolean bol = vo.getCreatePerson().equals(couponModel.getDoctId())
						&& (CouponSendWayEnum.FOLLOW_UP.getKey().equals(vo.getSendWay())
						|| CouponSendWayEnum.CONCLUSION.getKey().equals(vo.getSendWay()))
						|| CouponSendWayEnum.EXCHANGE.getKey().equals(vo.getSendWay());
				if (bol) {
					//有满减判断是否满足条件  满减(包含兑换券)||折扣
					boolean bol2 =
							((CouponTypeEnum.WITH_REDUCED_SECURITIES.getKey().equals(vo.getTheType())
									|| CouponTypeEnum.A_VOUCHER.getKey().equals(vo.getTheType()))
									&& vo.getFullLimit().doubleValue() <= price.doubleValue())
									|| CouponTypeEnum.DISCOUNT_COUPONS.getKey().equals(vo.getTheType());
					if (bol2){
						newCoupon.add(vo);
					}
				}
			}
			PageInfo<CouponVo> newCouponInfo = new PageInfo<>(newCoupon);

			return newCouponInfo;
		} else {
			//我的优惠券
			myCoupon = mapper.myCoupon(couponModel);
			//myCoupon = couponFilter(myCoupon,true);
			return new PageInfo<>(myCoupon);
		}
	}



	/**
	 * 优惠券过滤
	 * @param coupons
	 * @return
	 */
	@Override
	public List<CouponVo> couponFilter( List<CouponVo> coupons ,Boolean bool){
		Iterator<CouponVo> it = coupons.iterator();
		while (it.hasNext()) {
			CouponVo coupon = it.next();
			//固定时间
			String type = coupon.getValidModel();
			if (CouponValidModelEnum.FIXED_TIME.getKey().equals(type)
					&& coupon.getEndTime().getTime() < System.currentTimeMillis()){
				if (bool){
					it.remove();
				}else {
					coupon.setState(true);
				}

				//动态时间
			}else if(CouponValidModelEnum.DYNAMIC_TIME.getKey().equals(type)){
				Date creTime = coupon.getReceiveTime();
				Long day = coupon.getValidDay() - TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - creTime.getTime());
				//coupon.setNewEndTime(new Date(creTime.getTime() + TimeUnit.DAYS.toMillis(coupon.getValidDay()-1)));
				coupon.setNewEndTime(coupon.getInvalidEndTime());
				coupon.setDay(day);
				if (day < 0){
					if (bool){
						it.remove();
					}else {
						coupon.setState(true);
					}
				}
			}
		}
		return coupons;
	}

	/**
	 * 根据优惠劵领取记录主键查询优惠劵
	 * @param receiveId
	 * @return
	 */
	@Override
	public CouponEntity selectByReciveId(Long receiveId) {
		return mapper.selectByReciveId(receiveId);
	}

	/**
	 * s随访优惠券列表
	 * @param arrs
	 * @param sendId
	 * @param receiverId
	 * @return
	 */
	@Override
	public List<CouponVo> coupons(String arrs, Long sendId, int receiverId) {
		return mapper.coupons(arrs,sendId,receiverId);
	}


	/**
	 * 优惠券添加
	 * @param coupon
	 * @return
	 */
	@Override
	public int addCoupon(CouponQryParam coupon) {
		if (null == coupon){
			throw  new BusinessException("添加对象不能为空");
		}

		// 查询适应服务的优惠券是否重复
//            CouponModel model = new CouponModel();
//            model.setToSb(coupon.getToSb());
//            model.setIsSys(coupon.getIsSys());
//            model.setPubState(FlagEnum.IS.getKey());
//            List<Coupon> coupon1 = selectByModel(model);
//            if (coupon1 != null && !coupon1.isEmpty()){
//                throw new BusinessException("该适用服务已经存在");
//            }
		//查询对应服务折扣是否存在
		List<CouponEntity> coupons = mapper.selectByExample(
				TK.selectWhere(CouponEntity.class)
						.andEqualTo(CouponEntity::getIsSys,coupon.getIsSys())
						.andEqualTo(CouponEntity::getToSb,coupon.getToSb()).end());
				
		
		//医生券(折扣券)  || 平台&&折扣
		boolean dis = CouponChannelEnum.THE_DOCTOR.getKey().equals(coupon.getIsSys())
				|| (CouponChannelEnum.PLATFORM.getKey().equals(coupon.getIsSys()) &&
				CouponTypeEnum.DISCOUNT_COUPONS.getKey().equals(coupon.getTheType()));
		//平台兑换(满减) || 平台满减
		boolean full = (CouponChannelEnum.PLATFORM.getKey().equals(coupon.getIsSys())
				&&  CouponTypeEnum.WITH_REDUCED_SECURITIES.getKey().equals(coupon.getTheType()))
				|| (CouponChannelEnum.PLATFORM.getKey().equals(coupon.getIsSys()) && CouponTypeEnum.A_VOUCHER.getKey().equals(coupon.getTheType()));

		for(CouponEntity cou : coupons){
			//医生券(折扣券)  || 平台&&折扣
			if(dis && coupon.getDiscount().equals(cou.getDiscount())){
				throw new BusinessException("不能重复添加同服务且同折扣的优惠券");
				//兑换(满减) || 满减
			}else if(full && cou.getFullLimit().equals(coupon.getFullLimit())
					&& cou.getFullMoney().equals(coupon.getFullMoney())){
				throw new BusinessException("不能重复添加同服务且同满减的优惠券");
			}
		}

		//固定时间
		if (CouponValidModelEnum.FIXED_TIME.getKey().equals(coupon.getValidModel())){
			Date endTime = coupon.getEndTime();
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(endTime);
			calendar.set(Calendar.HOUR_OF_DAY,0);
			calendar.set(Calendar.MINUTE,0);
			calendar.set(Calendar.SECOND,0);
			endTime = calendar.getTime();
			coupon.setEndTime(endTime);
		}
		coupon.setCreateTime(new Date());
		coupon.setDecNumLimit(coupon.getNumLimit()== null ? 0 : coupon.getNumLimit());
		int rows = mapper.insertSelective(coupon.covert());
		return rows;
	}

	/**
	 * 优惠券修改
	 * @param coupon
	 * @return
	 */
	@Override
	public int updateCoupon(CouponEntity coupon) {
		coupon.setDecNumLimit(coupon.getNumLimit());
		// 查询适应服务的优惠券是否重复 (发布状态的)
		if (FlagEnum.IS.getKey().equals(coupon.getPubState())) {
			List<CouponEntity> coupon1 = mapper.selectByExample(
					TK.selectWhere(CouponEntity.class)
					.andEqualTo(CouponEntity::getToSb,coupon.getToSb())
					.andEqualTo(CouponEntity::getIsSys,coupon.getIsSys())
					.andEqualTo(CouponEntity::getPubState,FlagEnum.IS.getKey())
					.andNotEqualTo(CouponEntity::getId,coupon.getId()).end()
			);
			if (coupon1 != null && !coupon1.isEmpty()) {
				throw new BusinessException("该适用服务已经存在");
			}
		}
		return mapper.updateByPrimaryKeySelective(coupon);
	}

}
